package com.example.chandao.config;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.exception.NotRoleException;
import com.example.chandao.common.enums.ErrCode;
import com.example.chandao.common.exception.AppLoginException;
import com.example.chandao.common.exception.BusinessException;
import com.example.chandao.common.exception.MoveLoginException;
import com.example.chandao.common.model.ApiResult;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;
import java.util.Objects;

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {


    // 未登录异常：NotLoginException
    @ExceptionHandler(NotLoginException.class)
    public ApiResult handleNotLoginException(HttpServletRequest request, NotLoginException e) {
        log.error("NotLoginException --> URI: {}, method: {}, errorCode:{}, errorMsg:{}", request.getRequestURI(), request.getMethod(), ErrCode.UNAUTHORIZED.getCode(), e);
        return ApiResult.error(ErrCode.UNAUTHORIZED.getCode(), e.getMessage());
    }


    // 角色异常：NotRoleException
    @ExceptionHandler(NotRoleException.class)
    public ApiResult handleNotRoleException(HttpServletRequest request, NotRoleException e) {
        log.error("NotRoleException --> URI: {}, method: {}, errorMsg:{}", request.getRequestURI(), request.getMethod(), e);
        return ApiResult.error(ErrCode.FORBIDDEN.getCode(), e.getMessage());
    }


    // 权限异常：NotPermissionException
    @ExceptionHandler(NotPermissionException.class)
    public ApiResult handleNotPermissionException(HttpServletRequest request, NotPermissionException e) {
        log.error("NotPermissionException --> URI: {}, method: {}, errorMsg:{}", request.getRequestURI(), request.getMethod(), e);
        return ApiResult.error(ErrCode.FORBIDDEN.getCode(), e.getMessage());
    }


    // 处理自定义异常：BusinessException
    @ExceptionHandler(BusinessException.class)
    public ApiResult handleBusinessException(HttpServletRequest request, BusinessException e) {
        log.error("BusinessException --> URI: {}, method: {}, errorMsg:{}", request.getRequestURI(), request.getMethod(), e.getMessage());
        return ApiResult.warn(e.getMessage());
    }


    // 处理自定义异常：AppLoginException
    @ExceptionHandler(AppLoginException.class)
    public ApiResult handleAppLoginException(HttpServletRequest request, AppLoginException e) {
        log.error("BusinessException --> URI: {}, method: {}, errorMsg:{}", request.getRequestURI(), request.getMethod(), e.getMessage());
        if (Objects.isNull(e.getCode()))
            return ApiResult.error(ErrCode.UNAUTHORIZED_MOVE.getCode(), e.getMessage());
        return ApiResult.error(e.getCode(), e.getMessage());
    }

    // 处理自定义异常：MoveLoginException
    @ExceptionHandler(MoveLoginException.class)
    public ApiResult handleAppLoginException(HttpServletRequest request, MoveLoginException e) {
        log.error("BusinessException --> URI: {}, method: {}, errorMsg:{}", request.getRequestURI(), request.getMethod(), e.getMessage());
        if (Objects.isNull(e.getCode()))
            return ApiResult.error(ErrCode.UNAUTHORIZED_APP.getCode(), e.getMessage());
        return ApiResult.error(e.getCode(), e.getMessage());
    }

    // 处理Assert异常：IllegalArgumentException
    @ExceptionHandler(IllegalArgumentException.class)
    public ApiResult handleIllegalArgumentException(HttpServletRequest request, IllegalArgumentException e) {
        log.error("IllegalArgumentException --> URI: {}, method: {}, errorMsg: {}", request.getRequestURI(), request.getMethod(), e);
        return ApiResult.warn(e.getMessage());
    }


    // 处理@Validated异常：MethodArgumentNotValidException
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ApiResult handleMethodArgumentNotValidException(HttpServletRequest request, MethodArgumentNotValidException e) {
        log.error("MethodArgumentNotValidException --> URI: {}, method: {}, errorMsg:{}", request.getRequestURI(), request.getMethod(), e.getMessage());
        List<ObjectError> errors = e.getBindingResult().getAllErrors();
        StringBuilder builder = new StringBuilder();
        //errors.forEach(error -> builder.append(error.getDefaultMessage()).append(" "));
        String msg = errors.get(0).getDefaultMessage();
        builder.append(msg);
        return ApiResult.error(ErrCode.PARAM_ERROR.getCode(), builder.toString());
    }


    // 处理参数未传异常：MissingServletRequestParameterException
    @ExceptionHandler(MissingServletRequestParameterException.class)
    public ApiResult handleParamException(HttpServletRequest request, MissingServletRequestParameterException e) {
        String uri = request.getRequestURI();
        log.error("MissingServletRequestParameterException --> URI: {}, method: {}, error: {}", uri, request.getMethod(), e);
        if (uri.contains("/epro/app"))
            return ApiResult.error(ErrCode.UNAUTHORIZED_APP.getCode(), ErrCode.UNAUTHORIZED_APP.getMsg(), e.getMessage());
        else if (uri.contains("/epro/move"))
            return ApiResult.error(ErrCode.UNAUTHORIZED_MOVE.getCode(), ErrCode.UNAUTHORIZED_MOVE.getMsg(), e.getMessage());
        return ApiResult.error(ErrCode.SYS_ERROR.getCode(), ErrCode.SYS_ERROR.getMsg(), e);
    }


    // 处理运行时异常：Exception
    @ExceptionHandler(Exception.class)
    public ApiResult handleException(HttpServletRequest request, Exception e) {
        log.error("Exception --> URI: {}, method: {}, error: {}", request.getRequestURI(), request.getMethod(), e);
        return ApiResult.error(ErrCode.SYS_ERROR.getCode(), ErrCode.SYS_ERROR.getMsg(), e);
    }

}
